#ifndef _OCPP_ObliqueTilingScheme_H_
#define _OCPP_ObliqueTilingScheme_H_

#include "ObliqueNodeInfo.h"
#include "ObliqueTile.h"

namespace OCPP
{
	namespace Cesium
	{

		using ObliqueTilingBoxVec = std::vector<ObliqueTilingBox>;
		class ObliqueTilingBox
		{
		public:
			ObliqueTilingBox();
			void push(ObliqueNodeInfo nodeInfo);

			bool shouldSplit(gltfOptions options);

			void expand(ObliqueNodeInfo& nodeInfo);

			bool contains(ObliqueNodeInfo& nodeInfo);

			Json::Value toJson();

			ObliqueTilingBoxVec split();
			uint32 numGeode = 0;
			uint32 numVertex = 0;
			uint32 numBytesOfImage = 0;
			osg::BoundingBox box;
			ObliqueNodeInfoVec tiles;
			std::shared_ptr<ObliqueTilingLevel> nextLevel;
		};

		class ObliqueTilingLevel
		{
		public:
			ObliqueTilingLevel(uint32 level1);

			void push(ObliqueNodeInfo nodeInfo);

			void findNoChildNode();
			void split(gltfOptions options);

			String getNodePath();
			ObliqueTilingBoxVec boxGroupVec;
			uint32 level;

			ObliqueNodeInfoVec noChildNodeVec;
			osg::BoundingBox box;
			StringVector nodePath;
			std::weak_ptr<ObliqueTilingLevel> parent;
		};
		using ObliqueTilingLevelVec = std::vector<ObliqueTilingLevel>;
		using ObliqueTilingLevelPtrVec = std::vector<std::shared_ptr<ObliqueTilingLevel> >;

		class _Osg2CesiumExport ObliqueTilingScheme
		{
		public:
			ObliqueTilingScheme();

			void split(ObliqueAnalyst& analyst);

			void setOptionsPerLevel(std::vector<gltfOptions> options1) 
			{ 
				options = options1;
			}

			gltfOptions getOptionsByLevel(uint32 level);

			uint32 numTileNodes = 0;
			uint32 numTileLevel = 0;
			std::vector<gltfOptions> options;
			std::unique_ptr<ObliqueTilingLevel> topTilingLevel;
		};
	}
}

#endif // !_OCPP_ObliqueTilingScheme_H_
